package com.mysecurity.utils;

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * RedisCacheConfig 缓存配置
 *
 * @author LILIBO
 * @since 2021-12-15
 */
@Configuration
@EnableCaching // 开启缓存
public class RedisCacheConfig {

    /**
     * 自定义生成key的规则
     * 缓存对象集合中，缓存是以键值对形式保存的
     * 当不指定缓存的key时，SpringBoot会使用SimpleKeyGenerator生成key
     *
     * @return
     */
    @Bean
    public KeyGenerator keyGenerator() {
        return (target, method, params) -> {
            // 格式化缓存key字符串
            StringBuilder sb = new StringBuilder();
            // 追加类名
            sb.append(target.getClass().getName());
            // 遍历参数并追加
            for (Object obj : params) {
                sb.append(obj.toString());
            }
            return sb.toString();
        };
    }

    /**
     * 使用RedisFastJsonSerializer作为序列化对象
     *
     * @param connectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);

        RedisFastJsonSerializer serializer = new RedisFastJsonSerializer(Object.class);

        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);

        // Hash的key也采用StringRedisSerializer的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);

        template.afterPropertiesSet();
        return template;
    }

}